/*
 * Copyright 2008 Martin Probst
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.martinprobst.xqpretty;

import static com.martinprobst.xqpretty.XQueryParser.*;

import java.util.ArrayList;

import org.antlr.runtime.CharStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.RecognizerSharedState;
import org.antlr.runtime.Token;
import org.antlr.runtime.TokenSource;
import org.antlr.runtime.TokenStream;
import org.antlr.runtime.debug.DebugEventListener;
import org.antlr.runtime.debug.DebugParser;

public class DebugParserBase extends DebugParser {

  private final LazyTokenStream lazyInput;
  private CharStream source;
  private final ArrayList<TokenSource> lexerStack = new ArrayList<TokenSource>();

  public DebugParserBase(TokenStream input) {
    this(input, new RecognizerSharedState());
  }

  public DebugParserBase(TokenStream input, RecognizerSharedState state) {
    super(input, state);
    lazyInput = (LazyTokenStream)input;
  }

  public DebugParserBase(TokenStream input, DebugEventListener dbg) {
    super(input, dbg);
    lazyInput = (LazyTokenStream)input;
  }

  public void setCharSource(CharStream source) {
    this.source = source;
  }

  @Override
  public void reportError(RecognitionException e) {
    throw new RuntimeException(getErrorHeader(e) + " " + getErrorMessage(e, getTokenNames()), e);
  }

  ArrayList<String> errors = new ArrayList<String>();

  @Override
  public void emitErrorMessage(String message) {
    errors.add(message);
  }

  public void error(Token t, String message) {
    errors.add("line " + t.getLine() + ":" + t.getCharPositionInLine() + ": " + message);
  }

  protected boolean ftproblem() {
    int lookahead = input.LA(1);
    return (lookahead == ELEMENT || lookahead == ATTRIBUTE || lookahead == PROCESSING_INSTRUCTION)
        && ((input.LA(2) == NCName && input.LA(3) == LCURLY) || (input.LA(2) == NCName
            && input.LA(3) == COLON && input.LA(4) == NCName && input.LA(5) == LCURLY));
  }

  private static final boolean debug = false;

  public boolean pushXMLLexer() {
    // if (lazyInput.getSource() instanceof XMLLexer) return;
    if (debug) System.out.println("XML Lexer");
    lexerStack.add(lazyInput.getSource());
    XMLLexer xmlLexer = new XMLLexer(source);
    lazyInput.setSource(xmlLexer);
    return true;
  }

  public boolean pushXQueryLexer() {
    // if (lazyInput.getSource() instanceof XQueryLexer) return;
    if (debug) System.out.println("XQuery Lexer");
    lexerStack.add(lazyInput.getSource());
    XQueryLexer xqueryLexer = new XQueryLexer(source);
    lazyInput.setSource(xqueryLexer);
    return true;
  }

  public boolean popXMLLexer() {
    // if (lazyInput.getSource() instanceof XQueryLexer) return;
    if (debug) System.out.println("Pop XML Lexer");
    TokenSource tokenSource = lexerStack.remove(lexerStack.size() - 1);
    if (tokenSource instanceof XMLLexer) {
      ((XMLLexer)tokenSource).inElem = false;
    }
    lazyInput.setSource(tokenSource);
    return true;
  }

  public boolean popXQueryLexer() {
    // if (lazyInput.getSource() instanceof XMLLexer) return;
    if (debug) System.out.println("Pop XQuery Lexer");
    TokenSource tokenSource = lexerStack.remove(lexerStack.size() - 1);
    lazyInput.setSource(tokenSource);
    return true;
  }

}
